<template>
  <div class="my-calendar">
    <div class="full-jcalendar__main">
      <!--单日期模式-->
      <div>
        <div class="full-jcalendar-header">
          <span class="title-year" @click="showYearList">{{ year }}年</span>
          <span style="width:10px;"></span>
          <span class="title-month" @click="monthVisible = true">{{ month }}月</span>
          <span style="width:10px;" v-if="showLunarControl"></span>
          <label v-if="showLunarControl"><input type="checkbox" v-model="isLunar" @change="onLunarChange"/>农历</label>

          <!-- header 切换月份 -->
          <p class="prev-month" @click.stop="goPrev"><i class="icon iconfont icon-xiangzuojiantou"></i></p>
          <p class="next-month" @click.stop="goNext"><i class="icon iconfont icon-xiangyoujiantou"></i></p>
        </div>
        <!-- body  日期和事件 -->
        <div class="full-jcalendar__body">
          <div class="weeks">
            <strong class="week">日</strong>
            <strong class="week">一</strong>
            <strong class="week">二</strong>
            <strong class="week">三</strong>
            <strong class="week">四</strong>
            <strong class="week">五</strong>
            <strong class="week">六</strong>
          </div>
          <!--日期 周  行-->
          <div class="week-row" v-for="week in calendarDatas">
            <!--日期 日  单元格-->
            <div class="day-cell" v-for="day in week"
                 :class="[{'today': day.isToday,'not-optional':isNotOptional(day),'select':isSelect(day),'not-cur-month': !day.isCurMonth }]"
                 @click="onDateSelect(day)"
            >
              <!-- 日期 节气 农历 -->
              <div class="day-number">
                <slot :name="day.date" :data="day"></slot>
                <p class="solar">
                  <!--<span class="is-leap" v-if="day.lDate.isLeap && day.lDate.lMonth>10 &&day.lDate.IDayCn==='初一'">闰</span>-->
                  <span class="is-leap" v-if="day.lDate.isLeap && day.lDate.IDayCn==='初一'">闰</span>
                  <span
                    :class="['number',{'is-today':day.isToday,'is-empty':day.isToday && !day.lDate.isFestival && !day.lDate.isTerm}]"
                  >{{ day.isToday ? '今天' : day.day }}</span>
                </p>
                <p class="lunar" v-show="!day.isToday || day.lDate.isFestival || day.lDate.isTerm">
                  <span class="festival" v-if="day.lDate.isFestival">{{ day.lDate.festival[0] }}</span>
                  <span class="term" v-else-if="day.lDate.isTerm">{{ day.lDate.Term }}</span>
                  <!--<span v-else-if="day.lDate.IDayCn==='初一'">{{day.lDate.isLeap && day.lDate.lMonth>10?day.lDate.IMonthCn.replace('闰',''):day.lDate.IMonthCn}}</span>-->
                  <span v-else-if="day.lDate.IDayCn==='初一'">{{ day.lDate.IMonthCn.replace('闰', '') }}</span>
                  <span v-else>{{ day.lDate.IDayCn }}</span>
                </p>
              </div>
            </div>
          </div>
        </div>

        <!-- 月份切换 -->
        <div class="full-jcalendar__month" v-show="monthVisible">
          <div class="full-jcalendar-header">
            <span>{{ month }}月</span>
          </div>
          <div class="full-jcalendar__body">
            <ul class="data-list">
              <li @click="onMonthSelect(m-1)" v-for="m in 12" :key="m">{{ m }}月</li>
            </ul>
            <p class="clearfix"></p>
            <p class="close" @click="monthVisible=false">取 消</p>
          </div>
        </div>

        <!-- 年份切换 -->
        <div class="full-jcalendar__year" v-show="yearVisible">
          <div class="full-jcalendar-header">
            <span>{{ year }}年</span>
            <!-- header 年份翻页 -->
            <p class="prev-month" @click.stop="goYearPrevList"><i class="icon iconfont icon-xiangzuojiantou"></i></p>
            <p class="next-month" @click.stop="goYearNextList"><i class="icon iconfont icon-xiangyoujiantou"></i></p>
          </div>

          <div class="full-jcalendar__body">
            <ul class="data-list">
              <li :class="{'select-year':(m + startYear -1)==year,'curr-year':(m + startYear -1)==todayYear}"
                  @click="onYearSelect(m + startYear -1)" v-for="m in 12" :key="m"
              >{{ m + startYear - 1 }}
              </li>
            </ul>
            <p class="clearfix"></p>
            <p class="close" @click="yearVisible=false">取 消</p>
          </div>
        </div>
      </div>


      <div class="clearfix"></div>
    </div>


  </div>
</template>

<script>
import moment from 'moment'
import JDatePickerScript from '@/components/common/JDatePicker/jDatePicker'

export default {
  name: 'Calendar',
  cnName: '日历',
  props: {
    value: {
      type: [String, Date, Array],
      default: ''
    },
    format: {
      type: String,
      default: 'YYYY-MM-DD'
    },
    showLunarClass: {
      type: String,
      default: 'NUMBER'//共四种，FULLLUNAR－全农历格式：丁酉[鸡]年己酉月乙巳日；LUNAR－中文格式：丁酉[鸡]年七月廿三；NUMBER－数字格式：2017-09-13；MIX格式：丁酉(2017)[鸡]年七月廿三；
    },
    showBackYears: {
      type: Number,
      default: 2
    },
    showLunarControl: {
      type: Boolean,
      default: false
    },
    type:{
      type: String,
      default: "DATE",//DATE - 日期类型；DATERANGE － 时间段；
    },
    rangeSeparator:{
      type: String,
      default: "-",//时间段分隔符
    },
    pickerOptions:{
      type:Object,
      default:null
    },
    multiple: {
      type: Boolean,
      default: false
    }
  },
  data() {
    return {
      startYear:0,//年份列表的起始年份
      monthDay: '',//月份日期类型，用来比较日期
      selectDay:[],//type=daterange,存放点击选中的时间值；
      chooseDay:[],//type=daterange,存放鼠标移动所选时间段；
      year: 0,
      month: 0,
      year2: 0,
      month2: 0,
      isCurrMonth: true,
      calendarDatas: [],
      calendarDatas2: [],
      yearVisible: false,//年份选择开关
      monthVisible: false,//月份选择开关
      clearVisible:false,//清除按钮开关
      isLunar: false,//是否启用农历
      isLeap: false,//是否闰月
    }
  },
  created() {
    let month = moment()
    this.monthDay = month.toISOString();
    this.todayYear = month.year();
    this.loadCalendar();

    this.emitMonth()
  },
  methods: {
    isNotOptional(day){
      if (this.pickerOptions != null && this.pickerOptions != undefined && 'disabledDate' in this.pickerOptions) {
        return this.pickerOptions.disabledDate(new Date(day.date));
      }
      return false;
    },
    isChoose(day){
      //是否在选中时间段区域内
      if(this.type.toUpperCase() == 'DATERANGE') {
        if(this.chooseDay.length == 2){
          let currDay = moment(day.date);
          return currDay.isSameOrAfter(this.chooseDay[0]) & currDay.isSameOrBefore(this.chooseDay[1]) & day.isCurMonth;
        }
      }
      return false;
    },
    isSelect(day){
      return this.selectDay.includes(day.date);
    },
    onLunarChange() {
      if (this.value != null && this.value != '' && this.value.length > 0) {
        if (this.type.toUpperCase() == 'DATERANGE') {
          //时间段模式
          if (this.isLunar) {
            //由公历到农历
            //判断日期结果集中日期格式是否为农历，若是不作处理直接返回。
            if(this.value[0].indexOf('L')>-1) return;
            let beginDay       = JDatePickerScript.calendar.getLunar(this.value[0].replace(/L/,'').replace(/R/,''));
            let endDay         = JDatePickerScript.calendar.getLunar(this.value[1].replace(/L/,'').replace(/R/,''));
            let beginDayResult = 'L' + (beginDay.isLeap ? 'R' : '') + moment(new Date(beginDay.lYear + '-' + beginDay.lMonth + '-' + beginDay.lDay)).format('YYYY-MM-DD');
            let endDayResult   = 'L' + (endDay.isLeap ? 'R' : '') + moment(new Date(endDay.lYear + '-' + endDay.lMonth + '-' + endDay.lDay)).format('YYYY-MM-DD');

            this.$emit('change',[beginDayResult,endDayResult]);
            this.$emit('input' ,[beginDayResult,endDayResult]);
          } else {
            //由农历到公历
            //判断日期结果集中日期格式是否为农历，若不是不作处理直接返回。
            if(this.value[0].indexOf('L') == -1) return;
            let beginDay       = JDatePickerScript.calendar.getSolar(this.value[0]);
            let endDay         = JDatePickerScript.calendar.getSolar(this.value[1]);
            let beginDayResult = moment(new Date(beginDay.cYear + '-' + beginDay.cMonth + '-' + beginDay.cDay)).format('YYYY-MM-DD');
            let endDayResult   = moment(new Date(endDay.cYear + '-' + endDay.cMonth + '-' + endDay.cDay)).format('YYYY-MM-DD');

            this.$emit('change',[beginDayResult,endDayResult]);
            this.$emit('input' ,[beginDayResult,endDayResult]);
          }
        } else {
          //单日期模式
          let day,result = '';
          if (this.isLunar) {
            //由公历到农历
            //判断日期结果中日期格式是否为农历，若是不作处理直接返回。
            if(this.value.indexOf('L')>-1) return;
            day = JDatePickerScript.calendar.getLunar(this.value.replace(/L/,'').replace(/R/,''));
            result = 'L' + (day.isLeap ? 'R' : '') + moment(new Date(day.lYear + '-' + day.lMonth + '-' + day.lDay)).format('YYYY-MM-DD');
            this.$emit('change', result);
            this.$emit('input' , result);
          } else {
            //由农历到公历
            //判断日期结果中日期格式是否为农历，若不是不作处理直接返回。
            if(this.value.indexOf('L') == -1) return;
            day = JDatePickerScript.calendar.getSolar(this.value);
            result = moment(new Date(day.cYear + '-' + day.cMonth + '-' + day.cDay)).format('YYYY-MM-DD');
            this.$emit('change', new Date(result));
            this.$emit('input' , new Date(result));
          }
        }

      }
    },
    showYearList(){
      //公式：A ＝ 默认当前年所在页面的起始年；S ＝ 选择日期所在年份；Z(pagesize) = 12; Math.ceil : 向上入，有小数就向上＋1；
      // result = A - Math.ceil( (A-S) / Z ) * Z;
      let A = this.todayYear + parseInt(this.showBackYears) - 11;
      this.startYear = A - Math.ceil((A - this.year )/12) * 12;

      this.yearVisible = true;
    },
    goYearPrevList(){
      if(this.startYear<1912) return;
      this.startYear -= 12;
    },
    goYearNextList(){
      if(this.startYear>=this.todayYear + parseInt(this.showBackYears) - 11) return;
      this.startYear += 12;
    },
    goYearPrev(){
      this.monthDay = moment(this.monthDay).subtract(1,'years').toISOString();
      this.loadCalendar();
      this.emitMonth()
    },
    goYearNext(){
      this.monthDay = moment(this.monthDay).add(1,'years').toISOString();
      this.loadCalendar();
      this.emitMonth()
    },
    goPrev () {
      let newMonth = moment(this.monthDay).subtract(1, 'months');
      this.monthDay = newMonth.toISOString();
      this.loadCalendar()
      this.emitMonth()
    },
    goNext () {
      let newMonth = moment(this.monthDay).add(1, 'months');
      this.monthDay = newMonth.toISOString();
      this.loadCalendar()
      this.emitMonth()
    },
    onDateSelect(day){
      if(this.isNotOptional(day)) return
      let dayDate = new Date(day.date).toISOString()
      let result = day.date
      // if (this.isLunar) {
      //   let tip = 'L' + (day.lDate.isLeap ? 'R' : '')
      //   let date = new Date(day.lDate.lYear + '-' + day.lDate.lMonth + '-' + day.lDate.lDay).toISOString()
      //   result = tip + moment(date).format("YYYY-MM-DD")
      // }


      const index = this.selectDay.indexOf(result)
      if(this.multiple) {
        if(index !== -1) {
          this.selectDay.splice(index, 1)
        } else {
          this.selectDay.push(result)
        }
      } else {
        if(index !== -1) {
          this.selectDay = []
        } else {
          this.selectDay = [result]
        }
      }

     // this.monthDay = dayDate
      this.$emit('change', this.selectDay)
      this.$emit('on-click', result)
    },
    setSelectDays(days) {
      this.selectDay = days
    },
    onMonthSelect(command){
      let newMonth = moment(this.monthDay).month(command)
      this.monthDay = newMonth.toISOString();
      this.loadCalendar();
      this.monthVisible = false
      this.emitMonth()
    },
    onYearSelect(command){
      let newMonth = moment(this.monthDay).year(command)
      this.monthDay = newMonth.toISOString();
      this.yearVisible = false;
      this.monthVisible = true;
    },
    loadCalendar () {
      if(this.monthDay==null || this.monthDay == ''){
        this.monthDay = moment().toISOString();
      }

      let startDate = moment(this.monthDay).startOf('month').format('YYYY-MM-DD');
      let currentMonth = moment(startDate);
      this.year = currentMonth.year();
      this.month = currentMonth.month() + 1;
      this.calendarDatas = this.handleCalendar(currentMonth);

      if(this.type.toUpperCase() == 'DATERANGE'){
        //时间段模式
        let currentMonth2 = currentMonth.clone().add(1,'months');
        this.year2 = currentMonth2.year();
        this.month2 = currentMonth2.month() + 1;
        this.calendarDatas2 = this.handleCalendar(currentMonth2);
      }
    },
    handleCalendar(currentMonth){
      let start = currentMonth.clone()
      start.subtract(start.day(), 'd')
      let calendars = [];

      for (let iWeek = 0; iWeek < 6; iWeek++) {
        let week = []
        if (iWeek > 0 && !start.isSame(currentMonth, 'month')) {
          break;
        }
        for (let iDay = 0; iDay < 7; iDay++) {
          week.push({
            day: start.date(),
            isToday: start.isSame(new Date(), 'day'),
            isCurMonth: start.isSame(currentMonth, 'month'),
            weekIndex:iWeek,
            week: iDay,
            date: start.clone().format('YYYY-MM-DD'),
            lDate: JDatePickerScript.calendar.getLunar(start.toISOString()),
          });
          start.add(1, 'd')
        }
        calendars.push(week)
      }

      return calendars;
    },
    emitMonth() {
      const month = moment(this.monthDay).format('YYYY-MM')
      const start = this.calendarDatas[0][0].date
      const end = this.calendarDatas[this.calendarDatas.length  - 1][6].date
      this.$emit('month-change', month, {start, end})
    }
  }
}
</script>

<style lang="scss" scoped>
@import "./theme/public";

.my-calendar {
  position: relative;

  .full-jcalendar__main {
    position: relative;
    top: 0;
    left: 0;
    width: 100%;
    z-index: 1;
  }
  .full-jcalendar-header {
    display: flex;
    align-items: center;
    justify-content: center;
    height: 40px;
  }
  .full-jcalendar__body {
    height: auto;
    .weeks {
      .week {
        color: #333;
      }
    }

    .day-cell {
      border: 1px solid #c9c9c9;

      .day-number .solar {
        font-size: 14px;
      }
    }
  }
  .full-jcalendar__body .week-row {
    height: 80px;
  }
  .full-jcalendar__body .day-cell {
    display: flex;
    align-items: center;
    justify-content: center;
  }
}
</style>
